home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 4 / QRZ Ham Radio Callsign Database - Volume 4.iso / files / dsp / 56ktools / a5611.tz / a5611 / examples / rvb2.asm < prev    next >
Assembly Source File  |  1992-08-11  |  20KB  |  416 lines

  1. ;   filename: RVB2.ASM
  2. ;
  3. ;
  4. ;       This code is an optimized version of the reverberation algorithm
  5. ;       found in file RVB1.ASM.  This program makes use of the parallel
  6. ;       move functionality of the 56001.  While this tends to make the
  7. ;       code less readible, it does increase its speed.  This version
  8. ;       is intended to run on the DSP56000ADSx (Application Development
  9. ;       System)board rev #2, with memory expansion.  The memory should 
  10. ;       be configured figured for 8K p-memory, 16K x-memory, 8K y-memory.
  11. ;       
  12. ;       Further gains in algorithm speed could be realized on boards not
  13. ;       constrained by the ADS memory limitations.  For example, due to
  14. ;       the need for 4 comb filters' worth of storage (each using about 
  15. ;       3500 samples - which takes 4096 samples each after using the DSM
  16. ;       statement) to fit into the 16K available for the x memory, we
  17. ;       must start at address $0000.  Thus, we are forced to use all the
  18. ;       56000's internal memory for sample storage.  Without being forced
  19. ;       to start sample storage at $0000, the 56000's internal memory could
  20. ;       be used for coefficient storage, allowing better use of parallel 
  21. ;       x and y moves.
  22. ;
  23. ;                               Motorola DSP Group
  24. ;                               Austin, Texas
  25. ;
  26. ;**************************************************************************
  27. ; This program was originally available on the Motorola DSP bulletin board
  28. ; and is provided under a DISCLAIMER OF WARRANTY available from Motorola
  29. ; DSP Operation, 6501 William Cannon Dr. W Austin, Texas  78735-8598.
  30. ;**************************************************************************
  31. ;--------------------------------------------------------------------------
  32. ;       This reverberation program is a variation of the reverberation
  33. ;       system and structures as described by James Moorer's article entitled
  34. ;        'About this Reverberation Business', Computer Music Journal,
  35. ;        3(2):13-28, 1979
  36. ;
  37. ;       Structure is:
  38. ;                                                       .----------.
  39. ;                            .------------.   .-----.   | All Pass |
  40. ;                         +->| Comb Filter|-->| SUM |-->| Reverb   |
  41. ;   Note: All Comb        |  |   #1       |   '-----'   |          |
  42. ;         Filters         |  '------------'   ^  ^  ^   '----------'
  43. ;         Have a 1st      |  .------------.   |  |  |        |
  44. ;         Order IIR       |->| Comb Filter|---+  |  |    .---V---.
  45. ;         LPF in their    |  |   #2       |      |  |    | align |
  46. ;         feedback        |  '------------'      |  |    | delay |
  47. ;         loop            |  .------------.      |  |    '---|---'
  48. ;                         |->| Comb Filter|------+  |        |
  49. ;                         |  |   #3       |         |      -----   reverb         
  50. ;                         |  '------------'         |       \./     gain
  51. ;                         |  .------------.         |        |
  52. ;                         |->| Comb Filter|---------+        |
  53. ;                         |  |   #4       |                  |
  54. ;                         |  '------------'                  |
  55. ;                         |                                  V
  56. ;         .------------.  |        FIR gain          .----------.
  57. ;         |   Early    |  |         |\               |          |
  58. ;input -->| Reflection |--+---------|  >------------>|  summer  |--- output
  59. ;      |  |    FIR     |            |/               |          |
  60. ;      |  '------------'                             '----------'      
  61. ;      |                                                  ^
  62. ;      |                                                  |
  63. ;      |                             dry gain             |
  64. ;      |                              |\                  |
  65. ;      +------------------------------|  >----------------+
  66. ;                                     |/
  67. ;       
  68. ;.............................................................................
  69. ;  COMB FILTER SUB STRUCTURE:
  70. ;                                .-------.
  71. ;      comb i        .-----.     | long  |                    comb i
  72. ;      input  ------>| sum |---->| delay |-------+--------->  output
  73. ;                    '-----'     '-------'       |
  74. ;                       ^                        |
  75. ;                       |                        V
  76. ;                       |       /|            .-----.
  77. ;                       +-----<   ------------| sum |<--------+
  78. ;                               \|            '-----'         |
  79. ;                            fdbck i             |           / \  lpf i gain
  80. ;                             gain               V         /_____\
  81. ;                             gain           .----------.     |
  82. ;                                            | 1 sample |     |
  83. ;                                            |  delay   |-----+
  84. ;                                            '----------'
  85. ;.............................................................................
  86. ;   UNIT (ALL PASS) REVERBERATOR STRUCTURE:
  87. ;   based on Schroeder as outlined in Griesinger: 'Practical Processors and
  88. ;   Programs for Digital Reverberation', Audio in Digital Times, 7th AES
  89. ;   conference, Toronto, Ontario, 1989
  90. ;   (the structure outlined in Moorer is a variation of this)
  91. ;
  92. ;                               -g
  93. ;                            |\
  94. ;                +---------->|  >--------------------------+
  95. ;                |           |/                            |
  96. ;                |                                         |
  97. ;                |                                         V
  98. ;    unit        |    .-----.   .--------.       |\     .-----.       unit
  99. ;    input ------+--->| sum |-->| delay  |--+--->|  >-->| sum |-----> output
  100. ;                     '-----'   '--------'  |    |/     '-----'
  101. ;                        ^                  |   1-g**2
  102. ;                        |     g            | 
  103. ;                        |       /|         |
  104. ;                        +-----<  |---------+
  105. ;                                \|
  106. ;
  107. ;...........................................................................
  108. ;
  109. ;       one multi-tap fir structure - to handle early reflections
  110. ;
  111. ;       followed by 4 parallel comb (iir) filters (each comb having 
  112. ;       a first order LPF in its feedback loop
  113. ;       
  114. ;       followed by an 'allpass' reverberator whose output is then 
  115. ;       delayed so that its first output follows after the last "early
  116. ;       reflection" output 
  117. ;
  118. ;__________________________________________________________________________
  119. ;
  120.         opt cex
  121.         page 132
  122.  
  123. ;--------------------------------------------------constant declarations
  124. adc     equ     $ffef           ; ADC address
  125. dac     equ     $ffef           ; DAC address
  126.  
  127. ntap    equ     7               ; number of taps 
  128. ntapp10 equ     ntap+10         ; # taps + 10 for other variables
  129. tapmod  equ     ntapp10-1       ; number of taps minus 1         
  130. dlymx   equ     4000            ; length of delay line in samples
  131.  
  132. cmbdly1 equ     2205            ; COMB FILTER CONSTANTS
  133. cmbdly2 equ     2690            ; delay values (in samples)
  134. cmbdly3 equ     3175
  135. cmbdly4 equ     3440
  136.  
  137. cmbmod1 equ       3490          ; modulo for comb #1 delay line   THESE ARE
  138. cmbmod2 equ       3490          ;   "         "   #2   "   "      ALSO THE 
  139. cmbmod3 equ       3490          ;   "         "   #3  "    "     MAX DELAYS
  140. cmbmod4 equ       3490          ;   "         "   #4  "    "      ALLOWED FOR
  141.                                 ;                                 CHOSEN DSM
  142.                                 ;                                 VALUE
  143.  
  144. untrvbdly       equ     265                 ; delay     UNIT (or ALLPASS)
  145. unt_g           equ     0.7                 ; gains (g)    REVERBERATOR
  146. neg_g           equ     -unt_g              ;       (-g)
  147. one_m_g2        equ     (1-unt_g*unt_g)     ;   "   (1-g**2)
  148.  
  149.  
  150. cmb_g           equ     0.86            ; (OVERALL) COMB FILTER FEEDBACK GAIN 
  151.                                         ; controls reverb decay time: smaller
  152.                                         ; values give quicker decay, larger
  153.                                         ; values yield slower decay
  154.  
  155. lpf1            equ     0.408           ; lpf filter coefficient in the 
  156. lpf2            equ     0.448           ; feedback loop of the combs,
  157. lpf3            equ     0.476           ; these LPF's simulate the high freq
  158. lpf4            equ     0.496           ; attentuation in real acoustic reverb
  159.  
  160. fdbck1          equ     cmb_g*(1-lpf1)  ; actual comb feedback gain
  161. fdbck2          equ     cmb_g*(1-lpf2)  ; is determined by the lpf filter
  162. fdbck3          equ     cmb_g*(1-lpf3)  ; coefficient and the overall feed-
  163. fdbck4          equ     cmb_g*(1-lpf4)  ; back gain to insure stability
  164.  
  165.  
  166. aligndly                equ     1305    ; alignment delay (see diagram above)
  167. alignmod                equ     1390    ;     "     mod
  168.  
  169.         
  170. reverbg         equ     0.35            ; reverberation output gain value
  171. firg            equ     0.15            ; early rflctn FIR output gain value
  172. dryg            equ     0.9999-(reverbg+firg) ; dry signal gain is rest  
  173.                                         ; CHOOSE THE MIX YOU LIKE
  174.  
  175.  
  176.         org x:0
  177. chead1  dsm 3500                ; allocates 3500 data spaces for use as
  178. chead2  dsm 3500                ; comb filter tap delay lines, CHEAD1 refers
  179. chead3  dsm 3500                ; to the Comb filter HEAD (beginning) for 
  180. chead4  dsm 3500                ; filter #1  
  181.  
  182.         org x:$0f00
  183. ofst_bf dsm     ntapp10         ; this reserves "ntap" contiguous addresses
  184.         org x:ofst_bf           ; starting at the closest appropriate modulo
  185. ofst0   dc      1               ; x address space.  Then starts filling the 
  186. ofst1   dc      877             ; offset buffer at this location with   
  187. ofst2   dc      1561            ; the right delay values for the 
  188. ofst3   dc      1716            ; EARLY REFLECTION FIR
  189. ofst4   dc      1826
  190. ofst5   dc      3083      ; IMPORTANT - to get no delay for the first 
  191. ofst6   dc      3510      ; early reflection, use a "1".  This is due the use
  192.                           ; of an instruction code pre-decrement, a "0" value 
  193.                           ; will cause a maximum delay equal to the tap delay
  194.                           ; line length
  195.  
  196. untdly  dc      untrvbdly       ; define the UNIT REVERBERATOR delay
  197. untmod  dc      untrvbdly-1     ; modulo for    "         "
  198.  
  199. algndly dc      aligndly
  200. algnmod dc      alignmod
  201.  
  202.         org y:$0f00
  203. gain_bf dsm ntapp10
  204.         org y:gain_bf           ; starting at y address zero this reserves
  205.                                 ; "ntap" contiguous addresses then starts
  206.                                 ; filling these addresses with the desired
  207. gain0   dc      0.213           ; tap "gain" values for EARLY REFLECTION FIR
  208. gain1   dc      0.217           ; recommended by moorer
  209. gain2   dc      0.174           ;
  210. gain3   dc      0.135           ; it is recommended to keep many early 
  211. gain4   dc      0.153           ; reflection returns, as these are fed into
  212. gain5   dc      0.157           ; comb filters, than can contribute greatly
  213. gain6   dc      0.051           ; to the later impulse response density
  214. c1g2    dc      fdbck1
  215. c2g2    dc      fdbck2
  216. c3g2    dc      fdbck3
  217. c4g2    dc      fdbck4
  218. c1out   ds      1
  219. untg2   dc      neg_g
  220. untg3   dc      one_m_g2
  221. untg1   dc      unt_g
  222. firgain dc      firg
  223. drygain dc      dryg
  224. rvbgain dc      reverbg
  225.  
  226.         org y:0
  227. c1g1    dc      lpf1            ; comb #1 g1 (LPF gain)
  228. c2g1    dc      lpf2            ;      #2      
  229. c3g1    dc      lpf3            ;      #3
  230. c4g1    dc      lpf4            ;      #4
  231.  
  232.  
  233. sample   ds 1                   ; input sample storage address
  234. firout   ds 1                   ; early ref FIR OUTput storage address
  235.  
  236.                                 ; COMB filter    output storage address
  237. c2out  ds 1                     ;  "      "   #2   "       "       "
  238.  
  239. lpfst1  ds 1                    ;  "      "   #1 Low Pass Filter state
  240. lpfst2  ds 1                    ;  "      "   #2  "    "    "      "
  241. lpfst3  ds 1                    ;  "      "   #3  "    "    "      "
  242. lpfst4  ds 1                    ;  "      "   #4  "    "    "      "
  243.  
  244.                                 ; allocates modulo memory for the unit
  245. udlyln  dsm     300             ; (allpass) reverberator delay line 
  246.  
  247. algndlyln dsm   1400            ; allocates modulo memory for alignment delay  
  248.                                 ; line
  249.  
  250. dlyline dsm dlymx               ; allocates mod memory for the FIR delay line
  251.  
  252. ;--------------------------------------------------------------------------
  253.      org     p:$40              ; program start address
  254.  
  255. ; Set up ADS board in case of force break instead of force reset
  256.        movep #0,x:$FFFE         ;set bcr to zero
  257.        movec #0,sp              ;init stack pointer
  258.        movec #0,sr              ;clear loop flag
  259.  
  260. ; Set up the SSI for operation with the DSP56ADC16EVB
  261. ; The following code sets port C to function as SCI/SSI
  262.        move #$0,a0              ;zero PCC to cycle it
  263.        movep a0,x:$FFE1
  264.        move #$0001ff,a0
  265.        movep a0,x:$FFE1         ;write PCC
  266.  
  267. ; The following code sets the SSI CRA and CRB control registers for external
  268. ; continuous clock, synchronous, normal mode.
  269.        move #$004000,a0         ;CRA pattern for word length=16 bits
  270.        movep a0,x:$FFEC
  271.        move #$003200,a0    ;CRB pattern for continous ck,sych,normal mode
  272.        movep a0,x:$FFED    ;word long frame sync: FSL=0;ext ck/fs 
  273.  
  274. ; -------------------------------------------------------------------------
  275.                                 ; initialize registers MO,RO, etc
  276.         move #dlymx-1,m0        ; tap line modulus
  277.         move #dlyline,r0        ; start of delay line
  278.         move #0,n0              ; 
  279.  
  280.         move #tapmod,m1         ; tap gain line modulo
  281.         move #gain_bf,r1        ; tap gain & tap delay pointer
  282.  
  283.         move #cmbmod1,m2        ; initialize the modulo registers
  284.         move #cmbmod2,m3        ; for comb filter buffers 1 thru 5
  285.         move #cmbmod3,m4
  286.         move #cmbmod4,m5
  287.  
  288.         move #cmbdly1,n2        ; initialize the offset register
  289.         move #cmbdly2,n3        ; for Comb filters 1 thru 5
  290.         move #cmbdly3,n4
  291.         move #cmbdly4,n5
  292.  
  293.         move #chead1,r2         ; initialize the pointer values for
  294.         move #chead2,r3          Comb filters 1 thru 5
  295.         move #chead3,r4
  296.         move #chead4,r5
  297.  
  298.         move x:algnmod,m6       ; initialize alignment delay line
  299.         move x:algndly,n6       ; offset, modulo, and pointer registers
  300.         move #algndlyln,r6
  301.  
  302.         move x:untmod,m7        ; initialize unit reverberator (allpass)
  303.         move x:untdly,n7        ; offset, modulo, and pointer registers
  304.         move #udlyln,r7
  305.  
  306. ;---------------------------------------------------------------------------
  307. ; The following code polls the RDF flag in the SSI-SR and waits for RDF=1
  308. ; and then reads the RX register to retrieve the data from the A/D converter.
  309. ; Sample rate is controlled by DSP56ADC16 board.   
  310.  
  311. poll    jclr #7,x:$FFEE,poll     ;loop until RDF bit = 1
  312.         movep x:adc,a            ;get A/D converter data
  313. ;---------------------------------------------------------------------------
  314.         asr a
  315.         asr a                   ; obtain data sample 
  316.                                 ; and shift right for headroom
  317.         move a,y:sample         ; keep dry sample
  318.  
  319. ;  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  320. ; FIR for early reflections
  321.         move a,y:(r0)-          ; push sample into delay line
  322.         clr a   x:(r1),n0       ; clr A and load offset into N0
  323.         do #ntap,fir            ; loop over the (ntaps-1),exclude fb tap now
  324.            move y:(r1)+,y1      ;  "   "   "   gain   "      "  Y
  325.            move y:(r0+n0),x1    ; get delayed sample
  326.            mac x1,y1,a  x:(r1),n0 ; MAC gain and sample & update offset
  327. fir     move a,y:firout         ; save FIR OUTput to y memory
  328. ;  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  329. ; COMB 1
  330.         move x:(r2+n2),b        ; get delayed sample & put in b
  331.         move b,y:c1out          ; move output to y memory space
  332.  
  333.         move y:c1g1,x1                  ; get LPF filter coeff
  334.         move y:lpfst1,y1                ; get LPF filter state
  335.         mac x1,y1,b     y:(r1)+,x1      ; compute LPF output
  336.         move b,y:lpfst1                 ; save LPF output to LPF state
  337.  
  338.         move b,y1                       ; put LPF output in Y1
  339.         mac x1,y1,a     x:(r3+n3),b     ; compute feedback term in A
  340.         move a,x:(r2)-                  ; store output into delay queue
  341.  
  342. ;  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  343. ; COMB 2
  344.         move y:firout,a         ; comb filter #1 with LPF in feed back
  345.         move b,y:c2out          ; move output to y memory space
  346.  
  347.         move y:c2g1,x1                  ; get LPF filter coeff
  348.         move y:lpfst2,y1                ; get LPF filter state
  349.         mac x1,y1,b     y:(r1)+,x1      ; compute LPF output
  350.         move b,y:lpfst2                 ; save LPF output to LPF state
  351.  
  352.         move b,y1                       ; put LPF output in Y1
  353.         mac x1,y1,a     x:(r4+n4),b     ; compute feedback term in A
  354.         move a,x:(r3)-                  ; store output into delay queue
  355.  
  356. ;  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  357. ; COMB 3
  358.         move y:firout,a         ; comb filter #1 with LPF in feed back
  359.         move b,x0
  360.  
  361.         move y:c3g1,x1                  ; get LPF filter coeff
  362.         move y:lpfst3,y1                ; get LPF filter state
  363.         mac x1,y1,b     y:(r1)+,x1      ; compute LPF output
  364.         move b,y:lpfst3                 ; save LPF output to LPF state
  365.  
  366.         move b,y1                       ; put LPF output in Y1
  367.         mac x1,y1,a     x:(r5+n5),b     ; compute feedback term in A
  368.         move a,x:(r4)-                  ; store output into delay queue
  369. ;  -  -  -  -  -  -   -    -    -    -   -   -   -    -   -     -   - 
  370. ; COMB 4
  371.         move y:firout,a         ; 
  372.         move b,y0
  373.  
  374.         move y:c4g1,x1                  ; get LPF filter coeff
  375.         move y:lpfst4,y1                ; get LPF filter state
  376.         mac x1,y1,b     y:(r1)+,x1      ; compute LPF output
  377.         move b,y:lpfst4                 ; save LPF output to LPF state
  378.  
  379.         move b,y1                       ; put LPF output in Y1
  380.         mac x1,y1,a     y:(r1)+,x1      ; compute feedback term in A,c1out to x1
  381.         move a,x:(r5)-                  ; store output into delay queue
  382. ;  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  383.         move y:c2out,a          ; add output of add four combs
  384.         add x1,a                ;  c2out + c1out
  385.         add x0,a        y:(r7+n7),x0       ; +c3out
  386.         add y0,a        y:(r1)+,y1         ; +c4out
  387.  
  388. ;       asr a   
  389. ;  -  -  -  -  -  -  -  -  -   -   -      -   -    -   -  -  -    -  
  390. ;                               all pass unit reverberator                              
  391.         move a,x1
  392.         mpy x1,y1,b     y:(r1)+,y1
  393.  
  394.         mac x0,y1,b     y:(r1)+,y1      ; MAC into b for output (B CONTAINS OUTPUT)
  395.         move b,y:(r6)-
  396.  
  397.         mac x1,y1,a     y:(r6+n6),y1
  398.         move a,y:(r7)-          ; put new+g*delayed into delay line/inc r7
  399. ;  -    -     -     -     -     -     -     -     -     -     -      -     -
  400.         move y:rvbgain,y0
  401.         mpy y1,y0,a     y:(r1)+,x1
  402.  
  403.         move y:firout,y1
  404.         mac x1,y1,a     y:(r1)+,x1
  405.  
  406.         move y:sample,y1        ; mix in the dry sample
  407.         mac x1,y1,a             ; A now contains the output sample
  408.         asr a
  409. ;  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  410. ; Write DSP56ADC16 A/D converter data to the PCM-56
  411.  
  412.            move a,x:dac          ;write the PCM-56 D/A via SSI xmt reg.
  413.            jmp poll                ;loop indefinitely
  414.  
  415.            end
  416.